package com.ldoublem.loadingviewlib.view;

import com.ldoublem.loadingviewlib.view.base.LVBase;
import ohos.agp.animation.Animator;
import ohos.agp.components.AttrSet;
import ohos.agp.components.Component;
import ohos.agp.render.Canvas;
import ohos.agp.render.Paint;
import ohos.agp.utils.Color;
import ohos.agp.utils.Point;
import ohos.app.Context;

/**
 * Created by lumingmin on 16/6/23.
 */

public class LVGearsTwo extends LVBase implements Component.DrawTask {
    private float mWidth = 0f;
    private Paint mPaint, mPaintAxle;
    private Paint mPaintRing;
    private float mPadding;
    private float mWheelLength; // 齿轮高度
    private int mWheelSmallSpace = 10;
    private int mWheelBigSpace = 8;
    float mAnimatedValue = 0f;
    float hypotenuse = 0f;
    float smallRingCenterX = 0f;
    float smallRingCenterY = 0f;
    float bigRingCenterX = 0f;
    float bigRingCenterY = 0f;

    public LVGearsTwo(Context context) {
        this(context, null);
    }

    public LVGearsTwo(Context context, AttrSet attrSet) {
        this(context, attrSet, null);
    }

    public LVGearsTwo(Context context, AttrSet attrSet, String styleName) {
        super(context, attrSet, styleName);
        mPadding = dip2px(5);
        mWheelLength = dip2px(2f);
    }

    @Override
    protected void InitPaint() {
        mPaintRing = new Paint();
        mPaintRing.setAntiAlias(true);
        mPaintRing.setStyle(Paint.Style.STROKE_STYLE);
        mPaintRing.setColor(Color.WHITE);
        mPaintRing.setStrokeWidth(dip2px(1.5f));

        mPaint = new Paint();
        mPaint.setAntiAlias(true);
        mPaint.setStyle(Paint.Style.STROKE_STYLE);
        mPaint.setColor(Color.WHITE);
        mPaint.setStrokeWidth(dip2px(1));

        mPaintAxle = new Paint();
        mPaintAxle.setAntiAlias(true);
        mPaintAxle.setStyle(Paint.Style.FILL_STYLE);
        mPaintAxle.setColor(Color.WHITE);
        mPaintAxle.setStrokeWidth(dip2px(1.5f));
        addDrawTask(this);
    }

    @Override
    public void onDraw(Component component, Canvas canvas) {
        if (getWidth() > getHeight()) {
            mWidth = getHeight();
        } else {
            mWidth = getWidth();
        }
        canvas.rotate(180, mWidth / 2, mWidth / 2);
        drawSmallRing(canvas);
        drawSmallGear(canvas);
        drawBigGear(canvas);
        drawBigRing(canvas);
        drawAxle(canvas);
    }

    private void drawSmallRing(Canvas canvas) {
        hypotenuse = (float) (mWidth * Math.sqrt(2));
        smallRingCenterX = (float) ((hypotenuse / 6.f) * Math.cos(45 * Math.PI / 180f));
        smallRingCenterY = (float) ((hypotenuse / 6.f) * Math.sin(45 * Math.PI / 180f));
        mPaintRing.setStrokeWidth(dip2px(1.0f));
        canvas.drawCircle(mPadding + smallRingCenterX, smallRingCenterY + mPadding, smallRingCenterX, mPaintRing);
        mPaintRing.setStrokeWidth(dip2px(1.5f));
        canvas.drawCircle(mPadding + smallRingCenterX, smallRingCenterY + mPadding, smallRingCenterX / 2, mPaintRing);
    }

    private void drawSmallGear(Canvas canvas) {
        mPaint.setStrokeWidth(dip2px(1));
        for (int i = 0; i < 360; i = i + mWheelSmallSpace) {
            int angle = (int) (mAnimatedValue * mWheelSmallSpace + i);
            float x3 = (float) ((smallRingCenterX) * Math.cos(angle * Math.PI / 180f));
            float y3 = (float) ((smallRingCenterY) * Math.sin(angle * Math.PI / 180f));
            float x4 = (float) ((smallRingCenterX + mWheelLength) * Math.cos(angle * Math.PI / 180f));
            float y4 = (float) ((smallRingCenterY + mWheelLength) * Math.sin(angle * Math.PI / 180f));
            canvas.drawLine(new Point(mPadding + smallRingCenterX - x4, smallRingCenterY + mPadding - y4),
                    new Point(smallRingCenterX + mPadding - x3, smallRingCenterY + mPadding - y3), mPaint);
        }
    }

    private void drawBigGear(Canvas canvas) {
        bigRingCenterX = (float) ((hypotenuse / 2.f) * Math.cos(45 * Math.PI / 180f));
        bigRingCenterY = (float) ((hypotenuse / 2.f) * Math.sin(45 * Math.PI / 180f));
        float strokeWidth = dip2px(1.5f) / 4;
        mPaint.setStrokeWidth(dip2px(1.5f));
        for (int i = 0; i < 360; i = i + mWheelBigSpace) {
            int angle = (int) (360 - (mAnimatedValue * mWheelBigSpace + i));
            float x3 = (float) ((bigRingCenterX - smallRingCenterX) * Math.cos(angle * Math.PI / 180f));
            float y3 = (float) ((bigRingCenterY - smallRingCenterY) * Math.sin(angle * Math.PI / 180f));
            float x4 = (float) ((bigRingCenterX - smallRingCenterX + mWheelLength) * Math.cos(angle * Math.PI / 180f));
            float y4 = (float) ((bigRingCenterY - smallRingCenterY + mWheelLength) * Math.sin(angle * Math.PI / 180f));
            canvas.drawLine(new Point(bigRingCenterX + mPadding - x4 + mWheelLength * 2 + strokeWidth, bigRingCenterY + mPadding - y4 + mWheelLength * 2 + strokeWidth),
                    new Point(bigRingCenterX + mPadding - x3 + mWheelLength * 2 + strokeWidth, bigRingCenterY + mPadding - y3 + mWheelLength * 2 + strokeWidth), mPaint);
        }
    }

    private void drawBigRing(Canvas canvas) {
        float strokeWidth = dip2px(1.5f) / 4;
        mPaintRing.setStrokeWidth(dip2px(1.5f));
        canvas.drawCircle(bigRingCenterX + mPadding + mWheelLength * 2 + strokeWidth,
                bigRingCenterY + mPadding + mWheelLength * 2 + strokeWidth,
                bigRingCenterX - smallRingCenterX - strokeWidth, mPaintRing);
        mPaintRing.setStrokeWidth(dip2px(1.5f));
        canvas.drawCircle(bigRingCenterX + mPadding + mWheelLength * 2 + strokeWidth,
                bigRingCenterY + mPadding + mWheelLength * 2 + strokeWidth,
                (bigRingCenterX - smallRingCenterX) / 2 - strokeWidth, mPaintRing);
    }

    private void drawAxle(Canvas canvas) {
        for (int i = 0; i < 3; i++) {
            float x3 = (float) ((smallRingCenterX) * Math.cos(i * (360 / 3) * Math.PI / 180f));
            float y3 = (float) ((smallRingCenterY) * Math.sin(i * (360 / 3) * Math.PI / 180f));
            canvas.drawLine(new Point(mPadding + smallRingCenterX, mPadding + smallRingCenterY),
                    new Point(mPadding + smallRingCenterX - x3, mPadding + smallRingCenterY - y3), mPaintAxle);
        }
        for (int i = 0; i < 3; i++) {
            float x3 = (float) ((bigRingCenterX - smallRingCenterX) * Math.cos(i * (360 / 3) * Math.PI / 180f));
            float y3 = (float) ((bigRingCenterY - smallRingCenterY) * Math.sin(i * (360 / 3) * Math.PI / 180f));
            canvas.drawLine(new Point(bigRingCenterX + mPadding + mWheelLength * 2, bigRingCenterY + mPadding + mWheelLength * 2),
                    new Point(bigRingCenterX + mPadding + mWheelLength * 2 - x3, bigRingCenterY + mPadding + mWheelLength * 2 - y3), mPaintAxle);
        }
    }

    public void setViewColor(int color) {
        mPaint.setColor(new Color(color));
        mPaintAxle.setColor(new Color(color));
        mPaintRing.setColor(new Color(color));
        invalidate();
    }

    @Override
    protected void OnAnimationRepeat(Animator animation) {

    }

    @Override
    protected void OnAnimationUpdate(float value) {
        mAnimatedValue = value;
        invalidate();
    }

    @Override
    protected int OnStopAnim() {
        invalidate();
        return 1;
    }

    @Override
    protected int SetAnimRepeatMode() {
        return RESTART;
    }

    @Override
    protected void AinmIsRunning() {

    }

    @Override
    protected int SetAnimRepeatCount() {
        return Integer.MAX_VALUE;
    }


}
